/************************************************************************************
*    File Name:  rt72_mini_lvds_macro.v                                          
*     Revision:  V0.1                                                   
* Release Date:  2014/11/21                                              
*        Model:                                                          
* Dependencies:                                                          
*  Description:  LVDS Hard Macro For AUO12405                                         
*                                                          
*      Company:  AUO                                                     
*     Engineer:  Jie sc Ho                             
*  Create Date:  2014/11/18
*                                                                        
* Rev  Author      Date        Changes                                   
* ---  ----------  ----------  -------------------------------------------------------      

**************************************************************************************/

//`timescale 1ns/10ps
//`define FPGA
//`include "./def_fpga_sim.v"

module rt72_mini_lvds_macro(
 
 dclk,
 rclk,
 reset_n,
 in_end_frame,
 in_goa_endframe,
 in_xdio,
 chfb,
 
 in_bgi_rst_r,
 in_bgi_rst_f,
 in_vb_gray,
 in_bgi_width_en,
 in_bgi_width,
 
 in_sram0_lb1_wen,
 in_sram0_lb2_wen,
 in_sram1_lb1_wen,
 in_sram1_lb2_wen,
 
 in_sram0_lb1_cen,
 in_sram0_lb2_cen,
 in_sram1_lb1_cen,
 in_sram1_lb2_cen,
 
 in_sram0_lb1_dout,
 in_sram0_lb2_dout,
 in_sram1_lb1_dout,
 in_sram1_lb2_dout,
  
//`ifdef FPGA
//  out_fpgaf_r, out_fpgaf_g, out_fpgaf_b,
//  out_fpgab_r, out_fpgab_g, out_fpgab_b,
//`else

  out_mini_rst,
  out_fpr, out_fpg, out_fpb,
  out_bpr, out_bpg, out_bpb
//`endif

);

input        dclk;
input        rclk;
input        reset_n;
input        in_end_frame;
input        in_goa_endframe;
input        in_xdio;
input        chfb;

input        in_bgi_rst_r;
input        in_bgi_rst_f;
input [7:0]  in_vb_gray;
input        in_bgi_width_en;
input [10:0] in_bgi_width;

input        in_sram0_lb1_wen;
input        in_sram0_lb2_wen;
input        in_sram1_lb1_wen;
input        in_sram1_lb2_wen;

input        in_sram0_lb1_cen;
input        in_sram0_lb2_cen;
input        in_sram1_lb1_cen;
input        in_sram1_lb2_cen;

input [23:0] in_sram0_lb1_dout;
input [23:0] in_sram0_lb2_dout; 
input [23:0] in_sram1_lb1_dout; 
input [23:0] in_sram1_lb2_dout;

//`ifdef FPGA
//output [7:0] out_fpgaf_r, out_fpgaf_g, out_fpgaf_b;
//output [7:0] out_fpgab_r, out_fpgab_g, out_fpgab_b;
//`else

output out_mini_rst;
output [7:0] out_fpr, out_fpg, out_fpb;
output [7:0] out_bpr, out_bpg, out_bpb;
//`endif  

reg [23:0] in_sram0_lb1_dout_d1, in_sram0_lb2_dout_d1, 
           in_sram1_lb1_dout_d1, in_sram1_lb2_dout_d1;  //sram_dout data need to delay 1 stage(read clk domian)
always @(posedge rclk or negedge reset_n)
begin
 if (!reset_n)
  begin
  in_sram0_lb1_dout_d1 <= 24'd0;
  in_sram0_lb2_dout_d1 <= 24'd0;
  in_sram1_lb1_dout_d1 <= 24'd0;
  in_sram1_lb2_dout_d1 <= 24'd0;
    end else begin
        in_sram0_lb1_dout_d1 <= in_sram0_lb1_dout;
        in_sram0_lb2_dout_d1 <= in_sram0_lb2_dout;
        in_sram1_lb1_dout_d1 <= in_sram1_lb1_dout;
        in_sram1_lb2_dout_d1 <= in_sram1_lb2_dout;
        end
end
  

wire [7:0] in_sram0_lb1_r = chfb ? in_sram0_lb2_dout_d1 [23:16] : in_sram0_lb1_dout_d1 [23:16];
wire [7:0] in_sram0_lb1_g = chfb ? in_sram0_lb2_dout_d1 [15:8] : in_sram0_lb1_dout_d1 [15:8];
wire [7:0] in_sram0_lb1_b = chfb ? in_sram0_lb2_dout_d1 [7:0] : in_sram0_lb1_dout_d1 [7:0];

wire [7:0] in_sram0_lb2_r = chfb ? in_sram0_lb1_dout_d1 [23:16] : in_sram0_lb2_dout_d1 [23:16];
wire [7:0] in_sram0_lb2_g = chfb ? in_sram0_lb1_dout_d1 [15:8] : in_sram0_lb2_dout_d1 [15:8];
wire [7:0] in_sram0_lb2_b = chfb ? in_sram0_lb1_dout_d1 [7:0] : in_sram0_lb2_dout_d1 [7:0];

wire [7:0] in_sram1_lb1_r = chfb ? in_sram1_lb2_dout_d1 [23:16] : in_sram1_lb1_dout_d1 [23:16];
wire [7:0] in_sram1_lb1_g = chfb ? in_sram1_lb2_dout_d1 [15:8] : in_sram1_lb1_dout_d1 [15:8];
wire [7:0] in_sram1_lb1_b = chfb ? in_sram1_lb2_dout_d1 [7:0] : in_sram1_lb1_dout_d1 [7:0];

wire [7:0] in_sram1_lb2_r = chfb ? in_sram1_lb1_dout_d1 [23:16] : in_sram1_lb2_dout_d1 [23:16];
wire [7:0] in_sram1_lb2_g = chfb ? in_sram1_lb1_dout_d1 [15:8] : in_sram1_lb2_dout_d1 [15:8];
wire [7:0] in_sram1_lb2_b = chfb ? in_sram1_lb1_dout_d1 [7:0] : in_sram1_lb2_dout_d1 [7:0];


wire in_sram0_lb1_ren = in_sram0_lb1_wen ^ in_sram0_lb1_cen;
wire in_sram0_lb2_ren = in_sram0_lb2_wen ^ in_sram0_lb2_cen;
wire in_sram1_lb1_ren = in_sram1_lb1_wen ^ in_sram1_lb1_cen;
wire in_sram1_lb2_ren = in_sram1_lb2_wen ^ in_sram1_lb2_cen;

reg in_sram0_lb1_ren_d1, in_sram0_lb2_ren_d1, in_sram1_lb1_ren_d1, in_sram1_lb2_ren_d1;
//reg in_sram0_lb1_ren_d2, in_sram0_lb2_ren_d2, in_sram1_lb1_ren_d2, in_sram1_lb2_ren_d2;
always @(posedge rclk or negedge reset_n)
begin
 if (!reset_n)
  begin
  in_sram0_lb1_ren_d1 <= 1'd0;
  in_sram0_lb2_ren_d1 <= 1'd0;
  in_sram1_lb1_ren_d1 <= 1'd0;
  in_sram1_lb2_ren_d1 <= 1'd0;
  //in_sram0_lb1_ren_d2 <= 1'd0;
  //in_sram0_lb2_ren_d2 <= 1'd0;
  //in_sram1_lb1_ren_d2 <= 1'd0;
  //in_sram1_lb2_ren_d2 <= 1'd0;
  end
  else begin
       in_sram0_lb1_ren_d1 <= in_sram0_lb1_ren;
       in_sram0_lb2_ren_d1 <= in_sram0_lb2_ren;
       in_sram1_lb1_ren_d1 <= in_sram1_lb1_ren;
       in_sram1_lb2_ren_d1 <= in_sram1_lb2_ren;
       //in_sram0_lb1_ren_d2 <= in_sram0_lb1_ren_d1;
       //in_sram0_lb2_ren_d2 <= in_sram0_lb2_ren_d1;
       //in_sram1_lb1_ren_d2 <= in_sram1_lb1_ren_d1;
       //in_sram1_lb2_ren_d2 <= in_sram1_lb2_ren_d1;
       end  
end



// BGI function
reg in_bgi_rst_r_d1;
always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n)
  in_bgi_rst_r_d1 <= 1'd0;
  else 
  in_bgi_rst_r_d1 <= in_bgi_rst_r;
end

reg in_bgi_rst_f_d1;
always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n)
  in_bgi_rst_f_d1 <= 1'd0;
  else 
  in_bgi_rst_f_d1 <= in_bgi_rst_f;
end

wire in_bgi_rst_r_pe = in_bgi_rst_r & (~in_bgi_rst_r_d1);
wire in_bgi_rst_f_pe = in_bgi_rst_f & (~in_bgi_rst_f_d1);


reg bgi_rst;
always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n)
  bgi_rst <= 1'd0;
  else if (in_bgi_rst_r_pe)
       bgi_rst <= 1'd1;
       else if (in_bgi_rst_f_pe)
            bgi_rst <= 1'd0;
            else
            bgi_rst <= bgi_rst;
end

//reg bgi_xdio_pre_latch;
//always @( posedge rclk or negedge reset_n )
//begin
//  if (!reset_n)
//  bgi_xdio_pre_latch <= 1'd0;
//  else if (xdio_pre_cross)
//       bgi_xdio_pre_latch <= 1'd1;
//       else
//       bgi_xdio_pre_latch <= 1'd0;
//end
//
//reg bgi_rst;                                                // bgi_rst cross clk domain
//always @( posedge rclk or negedge reset_n )
//begin
//  if (!reset_n)
//  bgi_rst <= 1'd0;
//  else if (xdio_pre_latch)
//       bgi_rst <= 1'd1;
//       else
//       bgi_rst <= 1'd0;
//end


//bgi width counter
reg bgi_rst_d1;
always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n)
  bgi_rst_d1 <= 1'd0;
  else
  bgi_rst_d1 <= bgi_rst;
end

wire bgi_rst_pe = bgi_rst & (~bgi_rst_d1);
wire bgi_rst_ne = ~bgi_rst & bgi_rst_d1;


wire [10:0] bgi_width = in_bgi_width_en ? in_bgi_width : 10'd961;
reg bgi_en;
reg [10:0] bgi_width_cnt;
always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n )
  bgi_width_cnt <= 11'd0;
  else if (bgi_rst_ne)
       bgi_width_cnt <= 11'd0;
       else if (bgi_width_cnt == bgi_width)
            bgi_width_cnt <= 11'd0;
            else if (bgi_en)
            bgi_width_cnt <= bgi_width_cnt + 11'd1;
                 else
                 bgi_width_cnt <= 11'd0;
end


//reg bgi_en;


always @( posedge rclk or negedge reset_n )
begin
  if (!reset_n)
  bgi_en <= 1'd0;
  else if (bgi_rst_ne)
       bgi_en <= 1'd1;
       else if (bgi_width_cnt == bgi_width)
       bgi_en <= 1'd0;
       else
       bgi_en = bgi_en;
end



reg xdio_d1,  xdio_d2; // xdio_d3, xdio_d4, xdio_d5;
always @(posedge rclk or negedge reset_n)
begin
 if (!reset_n)
  begin
  xdio_d1 <= 1'd0;
  xdio_d2 <= 1'd0;
  //xdio_d3 <= 1'd0;
  //xdio_d4 <= 1'd0;
  //xdio_d5 <= 1'd0;
  end
  else begin
       xdio_d1 <= in_xdio;
       xdio_d2 <= xdio_d1;
       //xdio_d3 <= xdio_d2;
       //xdio_d4 <= xdio_d3;
       //xdio_d5 <= xdio_d4;
       end  
end
//
//wire xdio_d4_pe = xdio_d4 & (~xdio_d5);        //for fpga_rst



//`ifdef FPGA
//wire [7:0] out_fpgaf_r = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_r : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_r : 8'd0));
//wire [7:0] out_fpgaf_g = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_g : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_g : 8'd0));
//wire [7:0] out_fpgaf_b = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_b : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_b : 8'd0));

//wire [7:0] out_fpgab_r = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_r : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_r : 8'd0));
//wire [7:0] out_fpgab_g = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_g : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_g : 8'd0));
//wire [7:0] out_fpgab_b = xdio_d4_pe ? 8'b11111100 : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_b : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_b : 8'd0));

//`else

reg out_mini_rst;                              //out_mini_rst = xdio_d1
always @(posedge rclk or negedge reset_n)
begin
 if (!reset_n)
 out_mini_rst <= 1'd0;
 else
 out_mini_rst <= xdio_d2 | bgi_rst;
end

wire [7:0] out_fpr = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_r : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_r : 8'd0));
wire [7:0] out_fpg = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_g : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_g : 8'd0));
wire [7:0] out_fpb = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb1_b : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb1_b : 8'd0));

wire [7:0] out_bpr = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_r : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_r : 8'd0));
wire [7:0] out_bpg = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_g : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_g : 8'd0));
wire [7:0] out_bpb = bgi_en ? in_vb_gray : ((in_sram0_lb1_ren_d1 | in_sram0_lb2_ren_d1) ? in_sram0_lb2_b : ((in_sram1_lb1_ren_d1 | in_sram1_lb2_ren_d1) ? in_sram1_lb2_b : 8'd0));

//`endif



endmodule



